package net.seber.services.youtube.request;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import net.seber.services.youtube.data.YoutubeResult;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.util.DefaultPrettyPrinter;

public class YoutubeSearchRequest {

	private static final String ALT = "jsonc";
	private static final int VERSION = 2;
	private static final int DEFAULT_MAX_RESULTS = 10;
	private static final String YOUTUBE_API_URL = "http://gdata.youtube.com/feeds/api/videos";

	private String query;
	private String author;
	private int maxResults;
	private int startIndex;
	private HttpClient client;

	public YoutubeSearchRequest() {
		setMaxResults(DEFAULT_MAX_RESULTS);
		setStartIndex(1);
		client = new DefaultHttpClient();
	}

	public YoutubeSearchRequest(String query) {
		setQuery(query);
		setMaxResults(DEFAULT_MAX_RESULTS);
		setStartIndex(1);
		client = new DefaultHttpClient();
	}

	public YoutubeSearchRequest(String query, int maxResults) {
		setQuery(query);
		setMaxResults(maxResults);
		setStartIndex(1);
		client = new DefaultHttpClient();
	}

	public String getAuthor() {
		return author;
	}

	public void setAuthor(String author) {
		this.author = author;
	}

	public int getMaxResults() {
		return maxResults;
	}

	public void setMaxResults(int maxResults) {
		this.maxResults = maxResults;
	}

	public int getStartIndex() {
		return startIndex;
	}

	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
	}

	public void setQuery(String query) {
		this.query = query;
	}

	public String getQuery() {
		return query;
	}

	public YoutubeResult execute() {
		HttpGet httpget = new HttpGet(getRequestURL());
		System.out.println(httpget.getURI().toString());
		HttpResponse response;
		YoutubeResult result = null;
		try {
			response = client.execute(httpget);
			StatusLine status = response.getStatusLine();
			System.out.println("RESPONSE: " + status.getStatusCode() + " "
					+ status.getReasonPhrase());
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				InputStream instream = entity.getContent();
				int l;
				byte[] tmp = new byte[2048];
				while ((l = instream.read(tmp)) != -1) {
				}
				String json = new String(tmp);
				System.out.println(json);
				ObjectMapper objMapper = new ObjectMapper();
				result = objMapper.readValue(json, YoutubeResult.class);
				System.out.println(result.toString());
			}
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	public String getRequestURL() {
		StringBuilder urlBuilder = new StringBuilder(YOUTUBE_API_URL);
		int paramCount = 0;
		Map<String, Object> params = getQueryParameters();
		for (String key : params.keySet()) {
			String value = params.get(key).toString();
			try {
				value = URLEncoder.encode(value, "UTF-8");
			} catch (UnsupportedEncodingException e) {

			}
			if (value != null && value.length() > 0) {
				if (paramCount > 0) {
					urlBuilder.append("&");
				} else {
					urlBuilder.append("?");
				}
				urlBuilder.append(key);
				urlBuilder.append("=");
				urlBuilder.append(value);
				paramCount++;
			}
		}

		return urlBuilder.toString();
	}

	public Map<String, Object> getQueryParameters() {
		HashMap<String, Object> params = new HashMap<String, Object>();
		params.put("v", VERSION);
		params.put("alt", ALT);
		params.put("q", getQuery());
		params.put("max-results", getMaxResults());
		params.put("start-index", getStartIndex());
		return params;
	}

}
